package exec;

import exceptions.ForbiddenPortException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Server {

    private int numPort = 10006;
    private ServerSocket socket_ecoute = null;
    ClientList clientList = new ClientList();

    public Server(String[] args) {
        System.out.println("\n###### DriDri et JeanJean Project (and Simounet too) ######\n");
        System.out.println("Starting...OK");
        System.out.println("Parsing the Matrix...OK");
        
        try {
            if (args.length > 0) {
                numPort = Integer.parseInt(args[0]);
            }
            if (numPort < 1024) {
                throw new ForbiddenPortException();
            }
            socket_ecoute = new ServerSocket(numPort);

            while (true) {
                System.out.println("Waiting for client...");
                Socket socket_transfert = socket_ecoute.accept();
                Comm comm = new Comm(socket_transfert, this);
                Thread.sleep(100);
                System.out.println("Got client ! IP Adress : " + socket_transfert.getInetAddress() + " on port " + socket_transfert.getPort());
                comm.start();
                //Message m = new Message("2", "", "", "".getBytes());
            }
        } catch (Exception e) {
            System.out.println(e.toString());
        }
    }

    public static void main(String[] args) {
        new Server(args);
    }

    void parseMessage(Comm comm) throws InterruptedException {
        switch (comm.message.getType()) {
            case Message.CONNECT: {
                System.err.println("Case connect");
                if (clientList.hasClient(comm)) {
                    System.out.println("Nick already in use : " + comm.message.getNickSrc() + ". Got to kick it.");
                    try {
                        Message disconnect = new Message(Message.DISCONNECT, "Server", comm.message.getNickSrc(), "Error: Nick already in use");
                        comm.send(disconnect);
                        Thread.sleep(100);
                        comm.close();
                    } catch (InterruptedException ex) {
                        Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
                    }
                } else {
                    System.out.println("New client connected :  " + comm.message.getNickSrc());
                    comm.setName(comm.message.getNickSrc());
                    Message connect = new Message(Message.CONNECT, "Server", comm.message.getNickSrc(), "");
                    comm.send(connect);
                    clientList.addClient(comm);
                    Thread.sleep(100);
                    Message welcome = new Message(Message.MESSAGE, "Server", comm.message.getNickSrc(), "<b><i>Welcome to your favorite chat. Please Gangnam Style here.</i></b>");
                    comm.send(welcome);
                }
                break;
            }
            case Message.DISCONNECT:
                Thread.sleep(200);
                System.err.println("Case disconnect");
                System.out.println(comm.message.getNickSrc() + " Disconnected");
                Message disconnect = new Message(Message.DISCONNECT, "Server", comm.message.getNickSrc(), "You are now disconnected.");
                comm.send(disconnect);
                clientList.rmClient(comm);
                break;
            case Message.MESSAGE:
               System.err.println("Case message");
               if (clientList.hasClient(comm)) {
                   System.out.println(comm.message.getNickSrc() + " --> " + new String(comm.message.getData()));
                   System.out.println("SERVER : Got your message, " + comm.message.getNickSrc());
                   System.out.println("SERVER : Sending message to "+comm.message.getNickDest());
                   sendMessage(comm.message);
               } else
                   System.err.println("SERVER : You must be connected in order to send a message, you rebel !");
                break;
            case Message.LIST:
                break;
            case Message.WRITING:
                if (clientList.hasClient(comm) && !comm.message.getNickDest().equals("All")) {
                   sendMessage(comm.message);
               }
                break;
            case Message.NOT_WRITING:
                if (clientList.hasClient(comm) && !comm.message.getNickDest().equals("All")) {
                   sendMessage(comm.message);
               }
                break;
            case Message.FILENAME:
                System.err.println("Case File_Name");
                if (clientList.hasClient(comm)) {
                    System.out.println("Sending file " + new String(comm.message.getData()) + " to " + comm.message.getNickDest());
                    sendMessage(comm.message);
                } else
                    System.err.println("SERVER : You must be connected in order to send a file, you rebel !");
                break;
            case Message.FILESIZE:
               System.err.println("Case File_Size");
                if (clientList.hasClient(comm)) {
                    System.out.println("File size = " + new String(comm.message.getData()) + " bytes.");
                    sendMessage(comm.message);
                } else
                    System.err.println("SERVER : You must be connected in order to send a file, you rebel !");
                break;
            case Message.FILE_CHUNK:
               System.err.println("Case File_Chunk");
                if (clientList.hasClient(comm)) {
                    sendMessage(comm.message);
                } else
                    System.err.println("SERVER : You must be connected in order to send a file, you rebel !");
                break;
        }

    }
    private void sendMessage(Message message) {
        if (message.getNickDest().equals("All")) clientList.sendMessageToAll(message);
        else clientList.sendMessageToDest(message);
    }
}
